package org.zebra.redisson.queue;

import org.redisson.api.RPriorityBlockingQueue;
import org.zebra.redisson.util.RedissonUtil;

import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

/**
 * 优先队列
 *
 * @author zhanghongbin
 */
public final class PriorityQueue<V> {

    private static final Map<String, PriorityQueue> priorityQueueCache = new ConcurrentHashMap<>();

    private RPriorityBlockingQueue<V> priorityBlockingQueue;

    private PriorityQueue(RPriorityBlockingQueue<V> priorityBlockingQueue, Comparator<? super V> comparator) {
        this.priorityBlockingQueue = priorityBlockingQueue;
        this.priorityBlockingQueue.trySetComparator(comparator);
    }

    public RPriorityBlockingQueue<V> getPriorityBlockingQueue() {
        return priorityBlockingQueue;
    }

    public static <V> PriorityQueue<V> get(String queueName, Comparator<? super V> comparator) {
        PriorityQueue<V> priorityQueue = priorityQueueCache.get(queueName);
        if (priorityQueue == null) {
            priorityQueue =
                    new PriorityQueue<>(RedissonUtil.getClient().getPriorityBlockingQueue(queueName), comparator);
            priorityQueueCache.put(queueName, priorityQueue);
        }
        return priorityQueue;
    }

    /**
     * 添加优先队列数据
     *
     * @param data 数据
     */
    public boolean add(V data) {
        return priorityBlockingQueue.offer(data);
    }

    /**
     * 优先队列获取一个队列数据
     *
     * @return V 数据
     */
    public V consumer() {
        return priorityBlockingQueue.poll();
    }

    /**
     * 优先队列删除队列数据
     *
     * @param data 数据
     */
    public boolean remove(V data) {
        return priorityBlockingQueue.remove(data);
    }

    /**
     * 优先队列销毁队列 所有阻塞监听 报错
     */
    public boolean destroy() {
        return priorityBlockingQueue.delete();
    }

    /**
     * 订阅阻塞队列
     */
    public int consumer(Consumer<V> consumer) {
        return priorityBlockingQueue.subscribeOnElements(consumer);
    }
}
